package com.twu.biblioteca.controller;

import com.twu.biblioteca.domain.LibraryEntity;
import com.twu.biblioteca.domain.Withdrawable;
import com.twu.biblioteca.repository.Repository;

import java.util.List;


public class LibraryControllerImpl<T extends Withdrawable> implements LibraryController<T> {
    private Repository<T> bookRepository;
    private Repository<T> loanRepository;
    private LoginControllerImpl loginController;

    public LibraryControllerImpl(Repository<T> bookRepository, Repository<T> loanRepository, LoginControllerImpl loginController) {
        this.bookRepository = bookRepository;
        this.loanRepository = loanRepository;
        this.loginController = loginController;
    }

    @Override
    public void printItemList() {
        List<T> allLibraryItems = bookRepository.getAll();

        for (T libraryItem : allLibraryItems) {
            System.out.println(libraryItem);
        }
    }

    @Override
    public boolean withdrawItem(String bookId) {
        List<T> allLibraryItems = bookRepository.getAll();
        T desiredLibraryItem = getBookFromListById(bookId, allLibraryItems);

        if (desiredLibraryItem == null) {
            System.out.println("That book is not available.");
            return false;
        }

        withdrawBookAndNotifyUser(desiredLibraryItem);
        return true;
    }

    private void withdrawBookAndNotifyUser(T desiredLibraryItem) {
        desiredLibraryItem.setWithdrawn(loginController.getCurrentUser());
        bookRepository.remove(desiredLibraryItem);
        loanRepository.add(desiredLibraryItem);
        System.out.println("Thank you! Enjoy your withdrawal.");
    }

    private T getBookFromListById(String bookId, List<T> allLibraryItems) {
        T desiredLibraryItem = null;
        for (T libraryItem : allLibraryItems) {
            if (libraryItem.getId().equals(bookId))
                desiredLibraryItem = libraryItem;
        }

        return desiredLibraryItem;
    }

    @Override
    public boolean returnItem(String returnedBook) {
        List<T> loans = loanRepository.getAll();

        T matchingLibraryItem = getBookFromListById(returnedBook, loans);

        if (matchingLibraryItem == null) {
            System.out.println("The id you entered does not match an item that has been withdrawn.");
            return false;
        }

        returnBookAndNotifyUser(matchingLibraryItem);

        return false;
    }

    @Override
    public void printWithdrawn() {
        List<T> allLibraryItems = loanRepository.getAll();

        for (T libraryItem : allLibraryItems) {
            System.out.println(libraryItem);
        }
    }

    private void returnBookAndNotifyUser(T matchingLibraryItem) {
        matchingLibraryItem.setReturned();
        loanRepository.remove(matchingLibraryItem);
        bookRepository.add(matchingLibraryItem);
        System.out.println("Thank you for returning the book");
    }
}
